package com.wj.config.security;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wj.pojo.Role;
import com.wj.pojo.User;
import com.wj.service.IRoleService;
import com.wj.service.IUserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityGlobalConfig extends WebSecurityConfigurerAdapter {
    @Resource
    private MyAuthenticationSuccessHandler authenticationSuccessHandler;
    @Resource
    private MyAuthenticationFailureHandler authenticationFailureHandler;
    @Resource
    private IUserService userService;
    @Resource
    private IRoleService roleService;
    @Resource
    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;
    @Resource
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;

    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
        return username -> {
            User user = userService.getOne(new QueryWrapper<User>().eq("user_name", username));
            if (!ObjectUtils.isEmpty(user)){
                List<Role> roles=roleService.getUserWithRole(user.getId());
                user.setRoles(roles);
                return user;
            }
            throw new UsernameNotFoundException("用户名或密码错误");
        };
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService());
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                "/custom/works/**",
                "/test/**",
                "/**/**.jpg","/**/**.png","/index.html","/**/**.ttf",
                "/**/**.jpeg","/**/**.js","/**/**.css",
                "/series/works/getSeries"
        );
        web.ignoring().mvcMatchers(HttpMethod.GET, "/series/works/");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
                .and().formLogin().loginProcessingUrl("/dologin")
                .failureHandler(authenticationFailureHandler)
                .successHandler(authenticationSuccessHandler)
                .and().csrf().disable();

        //自定义的未授权和未登录响应
        http.exceptionHandling().accessDeniedHandler(restfulAccessDeniedHandler).authenticationEntryPoint(restAuthenticationEntryPoint);
        //限制会话数量
//        http.sessionManagement().maximumSessions(1);
        //关闭session的使用
//        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}